library(tidyverse)
library(data.table)
library(ggh4x)
library(lme4)
library(car)
library(ggeffects)
library(doParallel)

cores <- getOption("mc.cores", detectCores()) # for parallel computation
cl <- makeCluster(cores)
registerDoParallel(cl)

data loading

files <- dir("exp1_data_eyetracking_individual_saccades", ".*csv$", full.names = TRUE) 
dat <- c()

for (i in 1:length(files)) {
    d <- fread(files[i], header = TRUE)
    d$id <- i  # numeric variable for subject id
    dat <- rbind(dat, d)
}

dat <- subset(dat, dat$event == "fixation")
dat <- mutate(dat, target = apply(dat, 1, function(x){names(d)[13 + which.max(x[14:16])]}))
dat <- mutate(dat, dud = apply(dat, 1, function(x){names(d)[13 + which.min(x[14:16])]}))
dat$Condition <- as.factor(dat$Condition)
dat$target <- fct_recode(dat$target, up = "UVal", left = "LVal", right = "RVal")
dat$dud <- fct_recode(dat$dud, up = "UVal", left = "LVal", right = "RVal")
dat <- mutate(dat, fix = ifelse(item == target, "target", 
                         ifelse(item == dud, "dud",
                         ifelse(item == "noFix", "noFix", "distractor"))))

subject-wise fixation plot

plot1 <- foreach(i = 1:length(files), .packages = c("tidyverse", "ggh4x")) %dopar% {
    subset(dat, dat$id == i) %>%
    ggplot() + geom_point(aes(x = x, y = y, size = dur, color = Condition), alpha = 0.3) + 
        facet_nested(. ~ target + dud) + ggtitle(i) -> p
    print(p)
}
plot1
## [[1]]

## 
## [[2]]

## 
## [[3]]

## 
## [[4]]

## 
## [[5]]

## 
## [[6]]

## 
## [[7]]

## 
## [[8]]

## 
## [[9]]

## 
## [[10]]

Position-based fixation frequency

dat %>%
    group_by(Condition, target, dud, item, id) %>%
    summarise(n = n()) -> freq
## `summarise()` has grouped output by 'Condition', 'target', 'dud', 'item'. You
## can override using the `.groups` argument.
plot2 <- foreach(i = unique(freq$Condition), .packages = c("tidyverse", "ggh4x")) %dopar% {
    p <- ggplot(subset(freq, freq$Condition == i)) + geom_violin(aes(x = item, y = n, color = item)) + geom_point(aes(x = item, y = n)) + 
        facet_nested(. ~ target + dud) + 
        scale_x_discrete(limits = c("up", "left", "right", "noFix")) +
        scale_color_discrete(limits = c("up", "left", "right", "noFix")) + ggtitle(i)
    print(p)
}
plot2
## [[1]]
## Warning: Groups with fewer than two data points have been dropped.

## 
## [[2]]

## 
## [[3]]

## 
## [[4]]

## 
## [[5]]

## 
## [[6]]

Stimulus-based fixation frequency

dat %>%
    group_by(Condition, fix, id) %>%
    summarise(n = n()) -> fixation
## `summarise()` has grouped output by 'Condition', 'fix'. You can override using
## the `.groups` argument.
fixation$fix <- as.factor(fixation$fix)
fixation$fix <- factor(fixation$fix, levels = c("target", "distractor", "dud", "noFix"))

ggplot(fixation, aes(x = fix, y = n, color = Condition)) + geom_violin() + 
    geom_point(position = position_dodge(width = .9)) +
    stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9)) 
## Warning: The `fun.y` argument of `stat_summary()` is deprecated as of ggplot2 3.3.0.
## ℹ Please use the `fun` argument instead.

f1 <- lmer(n ~ fix * Condition + (1 + fix + Condition | id), data = fixation)
## boundary (singular) fit: see help('isSingular')
summary(f1)
## Linear mixed model fit by REML ['lmerMod']
## Formula: n ~ fix * Condition + (1 + fix + Condition | id)
##    Data: fixation
## 
## REML criterion at convergence: 2035.6
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -3.7493 -0.4887 -0.0345  0.4721  4.2394 
## 
## Random effects:
##  Groups   Name          Variance Std.Dev. Corr                               
##  id       (Intercept)    7676.65  87.617                                     
##           fixdistractor    48.79   6.985   0.09                              
##           fixdud         3970.27  63.010  -0.97  0.12                        
##           fixnoFix      13693.88 117.021  -0.92 -0.04  0.86                  
##           Condition0.3     48.40   6.957   0.53 -0.06 -0.45 -0.75            
##           Condition0.5     86.03   9.275   0.86  0.43 -0.72 -0.91  0.67      
##           Condition0.7    102.00  10.100   0.96  0.11 -0.89 -0.98  0.62  0.92
##           Condition0.85   258.02  16.063   0.79 -0.11 -0.75 -0.92  0.58  0.77
##           Condition0.95   373.44  19.325   0.82 -0.04 -0.77 -0.91  0.49  0.78
##  Residual                 365.58  19.120                                     
##             
##             
##             
##             
##             
##             
##             
##             
##   0.92      
##   0.93  0.99
##             
## Number of obs: 239, groups:  id, 10
## 
## Fixed effects:
##                             Estimate Std. Error t value
## (Intercept)                  395.600     28.359  13.950
## fixdistractor                -22.000      8.831  -2.491
## fixdud                      -381.514     21.788 -17.511
## fixnoFix                      -5.900     37.980  -0.155
## Condition0.3                 -16.800      8.829  -1.903
## Condition0.5                 -27.500      9.040  -3.042
## Condition0.7                 -39.200      9.128  -4.295
## Condition0.85                -32.700      9.946  -3.288
## Condition0.95                -31.700     10.510  -3.016
## fixdistractor:Condition0.3     5.700     12.093   0.471
## fixdud:Condition0.3           60.814     12.279   4.952
## fixnoFix:Condition0.3         26.200     12.093   2.167
## fixdistractor:Condition0.5     2.500     12.093   0.207
## fixdud:Condition0.5          110.814     12.279   9.024
## fixnoFix:Condition0.5         39.400     12.093   3.258
## fixdistractor:Condition0.7    -1.700     12.093  -0.141
## fixdud:Condition0.7          199.014     12.279  16.207
## fixnoFix:Condition0.7         52.600     12.093   4.350
## fixdistractor:Condition0.85  -16.000     12.093  -1.323
## fixdud:Condition0.85         253.814     12.279  20.670
## fixnoFix:Condition0.85        45.600     12.093   3.771
## fixdistractor:Condition0.95  -32.100     12.093  -2.655
## fixdud:Condition0.95         303.214     12.279  24.693
## fixnoFix:Condition0.95        38.900     12.093   3.217
## 
## Correlation matrix not shown by default, as p = 24 > 12.
## Use print(x, correlation=TRUE)  or
##     vcov(x)        if you need it
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
Anova(f1)
## Analysis of Deviance Table (Type II Wald chisquare tests)
## 
## Response: n
##                  Chisq Df Pr(>Chisq)    
## fix            500.795  3  < 2.2e-16 ***
## Condition       44.923  5  1.504e-08 ***
## fix:Condition 1411.950 15  < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(ggpredict(f1, terms = c("fix", "Condition"), type = "fe"))

Stimulus-based fixation frequency

fixation_prop1 <- c()

for (i in unique(fixation$id)) {
    for (j in unique(fixation$Condition)) {
        d <- subset(fixation,  fixation$id == i & fixation$Condition == j)
        s <- sum(d$n)
        fixation_prop1 <- rbind(fixation_prop1, mutate(d, prop = n/s))
    }
}

ggplot(fixation_prop1, aes(x = fix, y = prop, color = Condition)) + geom_violin() + 
    geom_point(position = position_dodge(width = .9)) +
    stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9)) 

Stimulus-based fixation frequency (noFix excluded)

fixation2 <- subset(fixation, fixation$fix != "noFix")
fixation_prop2 <- c()

for (i in unique(fixation2$id)) {
    for (j in unique(fixation2$Condition)) {
        d <- subset(fixation2,  fixation2$id == i & fixation2$Condition == j)
        s <- sum(d$n)
        fixation_prop2 <- rbind(fixation_prop2, mutate(d, prop = n/s))
    }
}

ggplot(fixation_prop2, aes(x = fix, y = prop, color = Condition)) + geom_violin() + 
    geom_point(position = position_dodge(width = .9)) +
    stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9)) 

Stimulus-based fixation frequency (noFix excluded)

fixation3 <- subset(fixation, fixation$fix == "target" | fixation$fix == "distractor")
fixation_prop3 <- c()

for (i in unique(fixation3$id)) {
    for (j in unique(fixation3$Condition)) {
        d <- subset(fixation3,  fixation3$id == i & fixation3$Condition == j)
        s <- sum(d$n)
        fixation_prop3 <- rbind(fixation_prop3, mutate(d, prop = n/s))
    }
}

ggplot(fixation_prop3, aes(x = fix, y = prop, color = Condition)) + geom_violin() + 
    geom_point(position = position_dodge(width = .9)) +
    stat_summary(fun.y = "mean", geom = "crossbar", position = position_dodge(width = .9))